<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    #demo {
      width: 300px;
      height: 300px;
      background: red;
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="demo">拖动</div>
  <script>
    let demo = document.querySelector('#demo')//待拖拽元素
    let canMove = false //拖拽状态
    let x = 0, y = 0 //鼠标位置
    //监听按下鼠标事件
    demo.onmousedown = function (e) {
      // 获取鼠标在元素在内部的位置
      x = e.pageX - demo.offsetLeft
      y = e.pageY - demo.offsetTop
      canMove = true //激活拖拽状态
    }
    //监听右击鼠标事件
    demo.oncontextmenu = function (e) {
      e.preventDefault()//阻止默认行为
    }
    //监听鼠标抬起事件
    window.onmouseup = function () {
      canMove = false//关闭拖拽状态
    }

    window.onblur = function () {//窗口失去焦点事件
      canMove = false//关闭拖拽状态
    }

    //监听鼠标移动事件
    window.onmousemove = function (e) {
      e.preventDefault();//阻止默认行为(字不能拖走)
      if (canMove) {//对范围判断

        // 获取点击位置距离游览器窗口的位置
        let left = e.pageX - x
        let top = e.pageY - y

        if (left < 0) left = 0 //当距离左边小于0时 让它为0
        if (top < 0) top = 0 //当距离上边小于0时 让它为0
        //右边距离为 标签距离左边最大距离(页面宽度减去div宽度得到)
        // window.innerWidth：游览器窗口宽度
        // demo.offsetWidth：选中的元素宽度
        let maxLeft = window.innerWidth - demo.offsetWidth // 防止当前元素跳出当前窗口
        //下边距离为 标签距离上边最大距离(页面高度减去div高度度得到)
        let maxTop = window.innerHeight - demo.offsetHeight

        if (left > maxLeft) left = maxLeft
        if (top > maxTop) top = maxTop


        demo.style.left = left + 'px'
        demo.style.top = top + 'px'

      }
    }




  </script>
</body>

</html>